<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function f1() {
            var n = 999;
            function f2() {
                console.log(n++);
            }
            return f2;
        }
        var result = f1();
        result(); //输出多少？999 先输出在加一
        result(); //输出多少？1000

        // 先f1入栈,将f2返回给result,f1出栈
        // 调用result()等价于f2()
        // 然后f2入栈，输出n(999),n++(1000),f2出栈
        // 再次调用result(),f2入栈，输出n(1000),n++(1001),f2出栈
        //  当一个函数调用时，一个新的执行上下文就会被创建。
        //  都是创建新的

        // 为什么f1调用完了n不释放掉
        // 因为f1调用返回f2，而result引用f2,使用着n
        // 所有n常驻内存，不释放

        // 可以实现外部访问内部的局部变量
        // 单例模式也可以实现

        var result2 = f1();
        result2(); //999
        // 创建了新的执行上下文环境

        var fun1, fun2;
        function foo() {
            var x = 10;
            fun1 = function() {
                console.log(++x);
            };
            fun2 = function() {
                console.log(--x);
            };
        }

        foo();
        fun1(); // ??    11
        fun1(); // ??    12
        fun2(); // ??    11

        foo();
        fun1(); // ??   11

        var fun1, fun2;
        function foo() {
            var x = 10;
            var fun1 = function() {
                console.log(++x);
            };
            var fun2 = function() {
                console.log(--x);
            };
        }

        foo();
        // fun1();  //报错 fun1 is not a function

    </script>
</body>
</html>